package com.codedef.service;

import com.codedef.entity.Classroom;
import com.codedef.entity.Seat;
import com.codedef.fservice.ClassroomService;
import com.codedef.fservice.SeatService;
import org.redisson.api.RLocalCachedMap;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 孙宏宇
 * @date 2021/2/18 14:42
 */
@Service
public class InitBloomService {

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    ClassroomService classroomService;

    @Autowired
    SeatService seatService;

    @Autowired
    BloomCacheManager bloomCacheManager;

    /**
     * 在服务启动时, 在Redis中建立所有座位的BloomFilter的缓存
     */
    public String initSeatListBloomCache() {
        RLock lock = redissonClient.getLock("BLOOM_CACHE_INIT");
        if (lock.tryLock()) {
            try {
                Date start = new Date();

                /* 查出所有的Classroom, 创建对应的CachedMap, 根据数据库中的预约记录, 重建布隆过滤器 */
                List<Classroom> classroomList = classroomService.getAll();

                for (Classroom classroom : classroomList) {
                    // 创建CachedMap
                    RLocalCachedMap cachedMap = bloomCacheManager.getCachedMap(classroom.getAbbreviation());

                    // 查数据库, 获取每个classroom所有座位, 放入cachedMap
                    List<Seat> seatList = seatService.getSeatListByClassroomId(classroom.getId());
                    Map<Integer, Integer> seatMap = seatList.stream().collect(Collectors.toMap(Seat::getId, i -> 0));
                    cachedMap.putAll(seatMap);  //放入座位列表本身

                    // 查数据库, 获取每个classroom当前有预约的SeatId的List, 修改这些座位的状态
                    List<Integer> nowReseSeatIdList = seatService.getNowReservationSeatIdListByClassroomIdFeign(classroom.getId());
                    System.out.println("nowReseSeatIdList: " + nowReseSeatIdList);
                    Map<Integer, Integer> reservationMap = nowReseSeatIdList.stream().collect(Collectors.toMap(i -> i, i -> 10));
                    cachedMap.putAll(reservationMap);
                }

                Date end = new Date();
                System.out.println( "initSeatListBloomCache 耗时：" + (end.getTime() - start.getTime()) );
                return "SUCCESS";
            } finally {
                lock.unlock();
            }
        }

        return "WAITING";
    } // END initSeatListBloomCache()

}
